package com.quantum.messaging.io;

import java.util.Arrays;
import java.util.List;

import flex.messaging.io.BeanProxy;
import flex.messaging.io.AbstractProxy;

public class EnumProxy extends BeanProxy {
	private static final long serialVersionUID = 1L;
	static final String ACTION_SCRIPT_KEY_NAME = "name";
	static String[] propertyNames = { ACTION_SCRIPT_KEY_NAME };

	@SuppressWarnings("unchecked")
	public Object createInstance(String className) {
		Class<?> clazz = AbstractProxy.getClassFromClassName(className);

		if (clazz.isEnum()) {
			return new EnumStub(clazz);
		} else
			throw new IllegalArgumentException("samples.EnumProxy registered for a class which is not an enum: " + clazz.getName());
	}

	public Object getValue(Object instance, String propertyName) {
		if (propertyName.equals(ACTION_SCRIPT_KEY_NAME)) {
			return instance.toString();
		} else {
			return super.getValue(instance, propertyName);
		}
	}

	public void setValue(Object instance, String propertyName, Object value) {
		EnumStub<?> es = (EnumStub<?>) instance;
		if (propertyName.equals(ACTION_SCRIPT_KEY_NAME))
			es.name = (String) value;
		else {
			super.setValue(instance, propertyName, value);
		}

	}

	@SuppressWarnings("unchecked")
	public Object instanceComplete(Object instance) {
		EnumStub es = (EnumStub) instance;
		return Enum.valueOf(es.clazz, es.name);
	}

	public List<String> getPropertyNames(Object instance) {
		if (!(instance instanceof Enum))
			throw new IllegalArgumentException("getPropertyNames called with non Enum object");
		return Arrays.asList(propertyNames);
	}

	class EnumStub<T extends Enum<T>> {
		EnumStub(Class<T> clazz) {
			this.clazz = clazz;
		}

		Class<T> clazz;
		String name;
	}

}
